package httpCtrler

import (
	"fmt"
	"github.com/go-xorm/xorm"
	st "kjjcgroup_server/model"
	sv "kjjcgroup_server/service"
	"kjjcgroup_server/units"
	"net/http"
	"strconv"
	"strings"
	"time"

	jwt "github.com/appleboy/gin-jwt"
	"github.com/gin-gonic/gin"
)

const (
	SessUserId       string = "0"
	SessUserName     string = "127.0.0.1"
	SessUserAccount  string = "USER"
	SessPermissionId string = "1"
	SessProjectId    string = "2"
	SessPassword     string = "false"
)

type _User struct {
	UserId       string `json:"UserId" `
	UserAccount  string `json:"UserAccount" `
	UserName     string `json:"UserName" `
	PermissionId string `json:"PermissionId" `
	ProjectId    string `json:"ProjectId" `
}

func Authenticator(c *gin.Context) (interface{}, error) {
	resDt := &struct {
		UserJson string `json:"user"`
	}{}
	err := c.BindJSON(resDt)
	if err != nil {
		return nil, err
	}
	mysql, err := sv.GetEngine()
	if err != nil {
		return nil, jwt.ErrFailedAuthentication
	}
	defer func(mysql *xorm.Engine) {
		err := mysql.Close()
		if err != nil {

		}
	}(mysql)
	mysql.ShowSQL(isShowSQL())
	// cookie, _ := c.Cookie("CheckTime")
	// fmt.Println("cookie=" + cookie)
	rtnDt := &_User{}
	res := &st.ModLoginSysUser{}
	loginUser := units.Base64ToJson(resDt.UserJson)
	if loginUser.User == "" {
		c.JSON(http.StatusOK, &MsgReturn{Msg: http.StatusText(http.StatusBadRequest), Data: "加密错误！"})
	}
	has, _ := mysql.Where("user_account=?", loginUser.User).Get(res)
	if !has {
		c.JSON(http.StatusOK, &MsgReturn{Msg: "用户名或者密码错误!", Data: nil})
		return nil, nil
	} else {
		// 先写缓存
		LoginNumAdd(loginUser.User) // 登陆次数加1
		c.Set(SessUserId, strconv.Itoa(res.UserId))
		c.Set(SessUserAccount, loginUser.User)
		c.Set(SessUserName, res.UserName)
		c.Set(SessPermissionId, strconv.Itoa(res.PermissionId))
		c.Set(SessProjectId, strconv.Itoa(res.ProjectId))
		c.Set(SessPassword, "false")
		if !has {
			return rtnDt, nil
		} else {
			password := units.TokenDecrypt(res.UserPassword)
			fmt.Println(password)
			if strings.EqualFold(password, loginUser.Password) {
				rtnDt.UserAccount = res.UserAccount
				rtnDt.UserId = strconv.Itoa(res.UserId)
				rtnDt.UserName = res.UserName
				rtnDt.PermissionId = strconv.Itoa(res.PermissionId)
				// 改变缓存正确的数据
				c.Set(SessUserId, rtnDt.UserId)
				c.Set(SessUserAccount, rtnDt.UserAccount)
				c.Set(SessUserName, res.UserName)
				c.Set(SessPermissionId, rtnDt.PermissionId)
				c.Set(SessProjectId, strconv.Itoa(res.ProjectId))
				c.Set(SessPassword, "true")
				return rtnDt, nil
			} else {
				return loginUser, nil
			}
		}
	}
}

func PayloadFunc(data interface{}) jwt.MapClaims {
	fmt.Println(74, "PayloadFunc in")
	if v, ok := data.(*_User); ok {
		fmt.Printf("PayloadFunc: %+v \r\n", v)
		return jwt.MapClaims{
			SessUserId:       v.UserId,
			SessUserAccount:  v.UserAccount,
			SessUserName:     v.UserName,
			SessPermissionId: v.PermissionId,
			SessProjectId:    v.ProjectId,
		}
	}
	return jwt.MapClaims{}
}

func LoginResponse(c *gin.Context, code int, token string, expire time.Time) {
	userAccount := ""
	userId := ""
	userName := ""
	ProjectId := ""
	PermissionId := ""
	Password := ""
	{
		v, _ := c.Get(SessUserAccount)
		v1, _ := c.Get(SessProjectId)
		v3, _ := c.Get(SessUserId)
		v4, _ := c.Get(SessPermissionId)
		v5, _ := c.Get(SessUserName)
		v7, _ := c.Get(SessPassword)
		userAccount = v.(string)
		userId = v3.(string)
		PermissionId = v4.(string)
		ProjectId = v1.(string)
		userName = v5.(string)
		Password = v7.(string)
	}
	myUserID, _ := strconv.Atoi(userId)
	myProjectId, _ := strconv.Atoi(ProjectId)
	if token != "" && userId != "" && Password != "false" {
		// 插入登陆表 ,或者 更新 登陆 TOKEN 并插入REDIS
		mysql, err := sv.GetEngine()
		if err != nil {
			return
		}
		defer func(mysql *xorm.Engine) {
			err := mysql.Close()
			if err != nil {
				return
			}
		}(mysql)
		t := time.Now()
		t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), 0, time.Local)
		_, _ = mysql.Cols("login_type", "log_ip", "user_id", "user_name", "user_account", "project_id", "status", "create_time").InsertOne(&st.SysLoginLog{LoginType: "web", LogIp: units.LocalIp(c), UserId: myUserID, UserName: userName, UserAccount: userAccount, ProjectId: myProjectId, Status: 1, CreateTime: t})
		/*记录TOKEN*/
	}
	if Password == "false" {
		mysql, err := sv.GetEngine()
		units.CheckError(err)
		defer DeferMysql(mysql)
		mysql.ShowSQL(isShowSQL())
		t := time.Now()
		t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), 0, time.Local)
		_, _ = mysql.Cols("login_type", "log_ip", "user_id", "user_name", "user_account", "project_id", "status", "create_time").InsertOne(&st.SysLoginLog{LoginType: "web", LogIp: units.LocalIp(c), UserId: myUserID, UserName: userName, UserAccount: userAccount, ProjectId: myProjectId, Status: 0, CreateTime: t})
		/*	c.JSON(http.StatusOK, gin.H{
				"msg":    "用户名名都密码错误",
				"ip":     units.GetLocalIP(),
				"netIp":  units.LocalIp(c),
				"expire": expire.Format(time.RFC3339),
			})
		*/
		// 换成返回base加密
		c.JSON(http.StatusOK, &MsgReturn{Msg: "用户名名都密码错误", Data: units.JsonToBase64(units.MapToJson(
			gin.H{
				"ip":     units.GetLocalIP(),
				"netIp":  units.LocalIp(c),
				"expire": expire.Format(time.RFC3339),
			},
		))})

	} else {
		// 换成返回base加密
		c.JSON(http.StatusOK, &MsgReturn{Msg: http.StatusText(http.StatusOK), Data: units.JsonToBase64(units.MapToJson(
			map[string]interface{}{
				"UserId":       userId,
				"UserAccount":  userAccount,
				"UserName":     userName,
				"PermissionId": PermissionId,
				"ProjectId":    ProjectId,
				"Ip":           units.GetLocalIP(),
				"NetIp":        units.LocalIp(c),
				"token":        token,
				"Expire":       expire.Format(time.RFC3339),
			},
		))})
	}

}

// Authorizator /* 成功拦截执行 true 放行 false 返回 403 */
func Authorizator(data interface{}, c *gin.Context) bool {
	//	log.Println("============成功访问的处理:查询表里有没有这个用户,如果有就对比下登陆TOKEN,如果查询到的TOKEN相同就放行,如果不同就返回FALSE,要求重新登陆=========")
	return true
}

// NoJwt /* 失败执行 */
func NoJwt(c *gin.Context, code int, message string) {
	c.JSON(code, gin.H{
		"code":    code,
		"success": false,
		"message": message,
	})
}
func Jwt(c *gin.Context) {
	c.JSON(http.StatusOK, nil)
}

func InsertLoginToken() {

}
